package com.dtp.common.entity;

import static java.util.stream.Collectors.toList;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;

import com.dtp.common.em.NotifyItemEnum;
import com.dtp.common.util.StringUtil;

import lombok.Data;
import lombok.val;

/**
 * 通知项信息
 *
 * @author yanhom
 * @since 1.0.0
 *
 * @remark muse
 **/
@Data
public class NotifyItem {
    @Deprecated
    private List<String> platforms;     // 通知平台名称（废弃属性，使用platformIds代替，在1.1.2被移除）请见：NotifyPlatformEnum
    private List<String> platformIds;   // 通知平台Id列表
    private boolean enabled = true;     // 是否开启通知，默认：开启
    private String type;                // 通知类型，请见：NotifyItemEnum
    private int threshold;              // 报警阈值
    private int interval = 120;         // 报警间隔，以秒为单位
    private int clusterLimit = 1;       // 集群通知限制

    /** 如果某些简单配置项（getSimpleNotifyItems）没有在source中被配置，则补充进去 */
    public static List<NotifyItem> mergeSimpleNotifyItems(List<NotifyItem> source) {
        if (CollectionUtils.isEmpty(source))
            return getSimpleNotifyItems(); // 初始化一个简单的通知项配置

        // 获得已配置的通知类型，即：source集合中的所有通知类型（type）集合
        val configuredTypes = source.stream().map(NotifyItem::getType).collect(toList());

        // 获得已配置的通知类型（configuredTypes）中没有配置的简单通知项（defaultItems）
        val defaultItems = getSimpleNotifyItems().stream()
                .filter(t -> !StringUtil.containsIgnoreCase(t.getType(), configuredTypes))
                .collect(Collectors.toList());
        source.addAll(defaultItems); // 将其维护到source中
        return source;

    }

    /** 如果某些全部配置项（getAllNotifyItems）没有在source中被配置，则补充进去 */
    public static List<NotifyItem> mergeAllNotifyItems(List<NotifyItem> source) {
        if (CollectionUtils.isEmpty(source)) return getAllNotifyItems(); // 如果source为空，则初始化一个完整的通知项配置

        // 获得已配置的通知类型，即：source集合中的所有通知类型（type）集合
        val configuredTypes = source.stream().map(NotifyItem::getType).collect(toList());

        // 获得已配置的通知类型（configuredTypes）中没有配置的全部通知项（defaultItems）
        val defaultItems = getAllNotifyItems().stream()
                .filter(t -> !StringUtil.containsIgnoreCase(t.getType(), configuredTypes))
                .collect(Collectors.toList());
        source.addAll(defaultItems); // 将其维护到source中
        return source;
    }

    /** 初始化一个简单的通知项配置，包含：CHANGE、LIVENESS 和 CAPACITY */
    public static List<NotifyItem> getSimpleNotifyItems() {
        // 对于【配置变更通知类型】，配置报警间隔为1秒
        NotifyItem changeNotify = new NotifyItem();
        changeNotify.setType(NotifyItemEnum.CHANGE.getValue());
        changeNotify.setInterval(1);

        // 对于【ThreadPool活跃度通知类型】，配置报警阈值为70
        NotifyItem livenessNotify = new NotifyItem();
        livenessNotify.setType(NotifyItemEnum.LIVENESS.getValue());
        livenessNotify.setThreshold(70);

        // 对于【容量阈值通知类型】，配置报警阈值为70
        NotifyItem capacityNotify = new NotifyItem();
        capacityNotify.setType(NotifyItemEnum.CAPACITY.getValue());
        capacityNotify.setThreshold(70);

        // 组装返回
        List<NotifyItem> notifyItems = new ArrayList<>(3);
        notifyItems.add(livenessNotify);
        notifyItems.add(changeNotify);
        notifyItems.add(capacityNotify);
        return notifyItems;
    }

    /** 初始化一个完整的通知项配置，包含：CHANGE、LIVENESS、CAPACITY、REJECT、RUN_TIMEOUT、QUEUE_TIMEOUT */
    public static List<NotifyItem> getAllNotifyItems() {
        // 对于【拒绝通知类型】，配置报警间隔为1
        NotifyItem rejectNotify = new NotifyItem();
        rejectNotify.setType(NotifyItemEnum.REJECT.getValue());
        rejectNotify.setThreshold(1);

        // 对于【任务运行超时告警通知类型】，配置报警间隔为1
        NotifyItem runTimeoutNotify = new NotifyItem();
        runTimeoutNotify.setType(NotifyItemEnum.RUN_TIMEOUT.getValue());
        runTimeoutNotify.setThreshold(1);

        // 对于【任务队列等待超时告警通知类型】，配置报警间隔为1
        NotifyItem queueTimeoutNotify = new NotifyItem();
        queueTimeoutNotify.setType(NotifyItemEnum.QUEUE_TIMEOUT.getValue());
        queueTimeoutNotify.setThreshold(1);

        // 组装返回
        List<NotifyItem> notifyItems = new ArrayList<>(6);
        notifyItems.addAll(getSimpleNotifyItems()); // 获得CHANGE、LIVENESS和CAPACITY的通知配置项
        notifyItems.add(rejectNotify);
        notifyItems.add(runTimeoutNotify);
        notifyItems.add(queueTimeoutNotify);

        return notifyItems;
    }
}
